  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="generator" content="pandoc" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <title>GTK 4 tutorial</title>
    <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre{overflow: visible;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::after
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {   }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span.al { color: #ff0000; font-weight: bold; } /* Alert */
      code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
      code span.at { color: #7d9029; } /* Attribute */
      code span.bn { color: #40a070; } /* BaseN */
      code span.bu { } /* BuiltIn */
      code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
      code span.ch { color: #4070a0; } /* Char */
      code span.cn { color: #880000; } /* Constant */
      code span.co { color: #60a0b0; font-style: italic; } /* Comment */
      code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
      code span.do { color: #ba2121; font-style: italic; } /* Documentation */
      code span.dt { color: #902000; } /* DataType */
      code span.dv { color: #40a070; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #40a070; } /* Float */
      code span.fu { color: #06287e; } /* Function */
      code span.im { } /* Import */
      code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
      code span.kw { color: #007020; font-weight: bold; } /* Keyword */
      code span.op { color: #666666; } /* Operator */
      code span.ot { color: #007020; } /* Other */
      code span.pp { color: #bc7a00; } /* Preprocessor */
      code span.sc { color: #4070a0; } /* SpecialChar */
      code span.ss { color: #bb6688; } /* SpecialString */
      code span.st { color: #4070a0; } /* String */
      code span.va { color: #19177c; } /* Variable */
      code span.vs { color: #4070a0; } /* VerbatimString */
      code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
      div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
      pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
      table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
      th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
      td {padding: 2px 6px; border: 1px solid;}
      img {display: block; margin-left: auto; margin-right: auto;}
      figcaption {text-align: center;}
    </style>
  </head>
  <body style="padding-top: 70px;">
    <div class="container">
    <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
      <div class="container-fluid">
        <span class="navbar-brand">Gtk4 tutorial</span>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>

            <li class="nav-item">
<a class="nav-link" href="sec22.html">Prev: section22</a>
</li>

            <li class="nav-item">
<a class="nav-link" href="sec24.html">Next: section24</a>
</li>

          </ul>
        </div>
      </div>
    </nav>
<h1 id="periodic-events">Periodic Events</h1>
<p>This chapter was written by Paul Schulz <a
href="mailto:paul@mawsonlakes.org"
class="email">paul@mawsonlakes.org</a>.</p>
<h2 id="how-do-we-create-an-animation">How do we create an
animation?</h2>
<p>In this section we will continue to build on our previous work. We
will create an analog clock application. By adding a function which
periodically redraws GtkDrawingArea, the clock will be able to
continuously display the time.</p>
<p>The application uses a compiled in ‘resource’ file, so if the GTK4
libraries and their dependencies are installed and available, the
application will run from anywhere.</p>
<p>The program also makes use of some standard mathematical and time
handling functions.</p>
<p>The clocks mechanics were taken from a Cairo drawing example, using
gtkmm4, which can be found <a
href="https://developer-old.gnome.org/gtkmm-tutorial/stable/sec-drawing-clock-example.html.en">here</a>.</p>
<p>The complete code is at the end.</p>
<h2 id="drawing-the-clock-face-hour-minute-and-second-hands">Drawing the
clock face, hour, minute and second hands</h2>
<p>The <code>draw_clock()</code> function does all the work. See the
in-file comments for an explanation of how the Cairo drawing works.</p>
<p>For a detailed reference of what each of the Cairo functions does see
the <a
href="https://www.cairographics.org/manual/cairo-cairo-t.html">cairo_t
reference</a>.</p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.c draw_clock @@@</p>
<p>In order for the clock to be drawn, the drawing function
<code>draw_clock()</code> needs to be registered with GTK4. This is done
in the <code>app_activate()</code> function (on line 24).</p>
<p>Whenever the application needs to redraw the GtkDrawingArea, it will
now call <code>draw_clock()</code>.</p>
<p>There is still a problem though. In order to animate the clock we
need to also tell the application that the clock needs to be redrawn
every second. This process starts by registering (on the next line, line
15) a timeout function with <code>g_timeout_add()</code> that will
wakeup and run another function <code>time_handler</code>, every second
(or 1000ms).</p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.c app_activate @@@</p>
<p>Our <code>time_handler()</code> function is very simple, as it just
calls <code>gtk_widget_queue_draw()</code> which schedules a redraw of
the widget.</p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.c time_handler @@@</p>
<p>.. and that is all there is to it. If you compile and run the example
you will get a ticking analog clock.</p>
<p>If you get this working, you can try modifying some of the code in
<code>draw_clock()</code> to tweak the application (such as change the
color or size and length of the hands) or even add text, or create a
digital clock.</p>
<h2 id="the-complete-code">The Complete code</h2>
<p>You can find the source files in the <code>tfc</code> directory. it
can be compiled with <code>./comp tfc</code>.</p>
<p><code>tfc.c</code></p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.c @@@</p>
<p><code>tfc.ui</code></p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.ui @@@</p>
<p><code>tfc.gresource.xml</code></p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/tfc.gresource.xml @@@</p>
<p><code>comp</code></p>
<p>@@<span class="citation" data-cites="include">@include</span>
tfc/comp @@@</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  </body>
  </html>
